#ifndef IO_SESSION_H
#define IO_SESSION_H
#include "message_context.h"
#include "io_session_config.h"
#include <boost/function.hpp>
namespace vpm
{
	namespace mina
	{
		//on java's mina , the session should not be subclass. should we provide it ?  
		class IoSessionAccessor;

		class IoSession
		{
		public:			
            IoSession()
            {
                m_bConnected =false; 
            }

            template<class Config> 
                IoSession(const Config &cfg)
                {
                    m_sessionConfig.reset(new Config()); 
                    *m_sessionConfig  = cfg; 
                    m_bConnected =false; 
                }


            virtual ~IoSession()
            {
			}
		
			virtual int read(MessageContext & msg)
			{		
				return m_readFunc(msg);
			}

			virtual int write(MessageContext & msg)
			{
				printf(" write message ?");
				return m_writeFunc(msg);
			}

			virtual int close()
			{
				if (m_closeFunc)
				{
					return m_closeFunc();
				}
				return 0; 
			}

			IoSessionConfig * get_session_config()
			{
				return m_sessionConfig.get(); 
			}
            template <class Config> 
                Config & get_session_config()
                {
                    return dynamic_cast<Config&> (*m_sessionConfig); 
                }

            bool is_connected()
            {
                return m_bConnected; 
            }

            void set_connect_state(bool flag)
            {
                printf("set connection state to %d\n",flag);
                m_bConnected = flag; 
            }


		protected:
			friend class IoSessionAccessor;	
			boost::function<int (MessageContext & )>  m_writeFunc; 
			boost::function<int (MessageContext & )>  m_readFunc; 
			boost::function<int ()> m_closeFunc;

            bool m_bConnected; 

			std::auto_ptr<IoSessionConfig > m_sessionConfig; 
		};

		class IoSessionAccessor
		{
		public:
			static void attach_reader(IoSession & session, boost::function<int (MessageContext & )> reader)
			{
				session.m_readFunc = reader;
			}

			static void attach_writter(IoSession & session, boost::function<int (MessageContext & )> writter)
			{
				session.m_writeFunc = writter;
			}
			static void attach_closer(IoSession & session, boost::function<int ()> closer)
			{
				session.m_closeFunc = closer;
			}
		};
	}
}

#endif //IO_SESSION_H


